/************************************************************************************************************************************************
 *   Copyright (C) 2008 by Denjs                                                                                                                *
 *   dplsoft@pisem.net                                                                                                                          *
 *   http://qdroid.berlios.de                                                                                                                   *
 * -----------------------------------------------------------------------                                                                      *
 *   This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or (at your option) any later version.                                      *
 *   This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                                 *
 *   You should have received a copy of the GNU General Public License along with this program; if not, write to the                            *
 *   Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                                                  *
 * -------------------------------------------------------------------------------------------------------------------------------------------- *
 *     Эта программа является свободным программным обеспечением; вы можете распространять её и/или модифицировать в соответствии с лицензией   *
 *   GNU General Public License  (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU) версии 2.0 или более поздней - на ваш выбор.                         *
 *     Эта программа распространяется  в надежде что она будет вам полезна, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, подразумеваемых или явных; без обещаний *
 *   полезности или применимости в конкретных условиях. Вы используете  данное ПО на свой страх и риск и сами полностью несете                  *
 *   ответственность за последствия. См. GNU General Public License (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU).                                  *
 *     Вы должны получить копию GNU General Public License (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU)с данным ПО; Если этого не случилось,       *
 *   обратитесь в Фонд Свободного Программного Обеспечения :                                                                                    *
 *   Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                                                  *
 * -------------------------------------------------------------------------------------------------------------------------------------------  *
 * Замечания для территории России: в соответствии с ГК РФ часть 4, начиная использовать данную программу (исполняемые файлы или исходные       *
 * тексты) вы автоматически соглашаетесь с данной лицензией.
 ************************************************************************************************************************************************/
/*::[[@stdinreader]] [[:buildin_classes]]
**stdInReader** - класс для работы с потоками STDIN|STDOUT|STDERR.
. \n
См также:
  * [[childprocess]] ((класс для запуска дочерненго процесса. предоставляет интерфейс для работы с потоками ввода-вывода дочернего процесса);

Общие характеристики:
  * имя конструктора QtScript: -не предоставляет- ;
    * QDroid создает единстввенный объект данного класса, \n доступный через переменную [[stdstreamsgate|StdStreamsGate]]
  * C++ имя класса : stdInReader наследован от QThread ;
  * Являетля встроенным классом.
  * Требует для нормальной работы загруженного расширения : [[qdlib_bytearray]] (TODO:сделать bytearray встроенным классом!)

----
  ver.2009.09.23 (альфа)
  ver.2009.09.14 (естественно альфа, но работает и это главное)

*/

//  UTF-8 russian encoded file


#include <QApplication>
#include <QtCore>
#include <QThread>
#include <QFile>
#include <QDebug>

//as in OTPD)
// Linux :
#if defined (Q_WS_X11)
        /* nothing needs to be included here yet...*/
// Win :
#elif defined (Q_WS_WIN)
        // for Sleep() :
        #include <windows.h>
// Mac:
#elif defined (Q_WS_MAC)
        /* NOT SUPPORTED THIS VERSION */
#else
        /* NOT SUPPORTED THIS VERSION */
#endif


/*::----
===Общее описание===

Сценарий использования включает следующие команды:
сначала int stdInReader::[[#open|open]](); - производится попытка открыть файловые дискрипторы потоков ввода/вывода; \n
Потом void stdInReader::[[#start|start]](); - начинается обработка данных. \n
При этом, генерируемые сигналы о поступлении данных на STDIN зависят от реима кеширования.
    * Если режим кеширования включен - то при поступлении данных посылается сигнал stdIn_readyRead \n и данные надо считать функцией [[stdin_Read|stdin_Read]]
    * Если режим кеширования отключен - до данные пересылаются вместе с сигналом [[stdIn_received|stdIn_received]].
Что-бы приостановить обработку данных выполните void stdInReader::[[stop|stop]](); \n
Что бы закрыть дискрипторы потоков ввода вывода, выполните int stdInReader::[[close|close]](); \n
\n
Родительская среда может закрыть поток ввода со своей стороны. Таким образом например некоторые утилиты Linux сообщают,
что это все данные которые они хотели передать и более данных не будет. после получения сигнала [[stdIn_StreamClosed|stdIn_StreamClosed]].

----
====Методы и свойства класса====
*/

#define maxCashSize 16383

class stdInReader : public QThread //::====$0 $1====\n   ***$*** \n
 {
 Q_OBJECT

 public: //::===Секция $* (С++)===
        int DebugLevel;//::  * **$*** \n уровень отладки 0-нет логов; 5-пошаговый с дампами переменных. некоторые режимы могут быть не реализованы.
        stdInReader(QObject * parent = 0);//::  * **$*** \n конструктор
        void run(); //::  * **$*** \n запуск потока на выполение.

 signals: //::===Секция $* (С++\QtScript)===
        void stdIn_received(const QByteArray &data); //::  * **$*** \n получены данные на STDIN. С сигналом присылает данные . генерируется только когда режим кеширования отключен.
        void stdIn_readyRead();		//::  * **$*** \n сигнал о том, что есть данные для чтения в приемном буфере. генерируется при включенном режиме кеширования.
        void stdIn_CashOverflow();	//::  * **$*** \n переполнениее входного кеша. данные не будут приниматься до очищения стека. Генерируется только при вклченном режиме кеширования.
        void stdReader_Opened();	//::  * **$*** \n Канал чтения STDIN открыт.
        void stdReader_Closed();	//::  * **$*** \n Канал чтения STDIN закрыт.
        void stdIn_StreamClosed();	//::  * **$*** \n Входной поток закрыт внешним приложением (родительским).Больше данных на STDIN не будет.
        void stdIn_ChangedCashMode(bool stdInCashMode);//::  * **$*** \n отсылается при изменении режима кеширования при пересылке данных.

 public slots: //::===Секция $* (С++\QtScript)===
        int open(bool _needAllStreams=false); //::  * **$*** \n запустить потоки чтения и записи и перейти в режим готовности к выполнения.
        //::^Возвращаемые значения ^^
        //::| 1 |already opened (if some errors was happened, but not critical) |
        //::| 0 |of all ok |
        //::|error code is summ of next values: ||
        //::|-1  if can`t oopen stdIn ||
        //::|-2  if can`t oopen stdOut ||
        //::|-4  if can`t oopen stdErr ||

        int close(bool failedInit=false);//::  * **$*** \n  закрыть все потоки

/**/	int send_StdOut(const QByteArray &_data);//<::  * **$*** \n Отослать данные на STDOUT
/**/	int send_StdErr(const QByteArray &_data);//<::  * **$*** \n Отослать даннын на STDERR
        /* start - standart slot*/
        void stop();//::  * **$*** \n  Остановить обработку потоков.(но не закрыть файловые дискрипторы)

        QByteArray stdin_Read(int maxSize);//::  * **$*** \n Прочитать с потока STDIN данные.
        int stdin_GetCashSize();//::  * **$*** \n получить размер кеша
        bool sdtin_waitFirReadyRead(int maxTimeMs);//::  * **$*** \n ожидать поступления данных maxTimeMs милисекунд.
//	void changedCashMode(bool stdInCashMode); //  * **$*** \n получить текущий режим пересылки данных.
        void stdIn_SetCachedMode();	//::  * **$*** \n установить [[режим кеширования при пересылке данных]] \n при послуплении дангных будет инициироваться сигнал что послупили данные, и далее надо будет из считать
        void stdIn_SetDataFlowMode();	//::  * **$*** \n установить [["прямоточный" режим пересылки данных]].\n поступающие данные будут отсылаться вместе с сигналом

 private:
        QFile stdIn;
        QFile stdOut;
        QFile stdErr;
        QByteArray data;
        bool inited;

        void from_stdin_buffer(QByteArray Message);//внутренний обработчик данных. он же занимается буфризацией
        int sleepMS( unsigned int time);

        QByteArray stdInCash;// кеш для
        bool stdInCashMode;//
        bool stdin_ReadyRead;

 };
